#ifndef SEARCHALGORITHM_H
#define SEARCHALGORITHM_H

#include "puzzlestate.h"
#include "searchnode.h"
#include <vector>
#include <string>

// 搜索结果结构体
struct SearchResult {
    bool success;                  // 是否找到解决方案
    std::string algorithmName;     // 算法名称
    std::vector<PuzzleState> path; // 解决路径
    int steps;                     // 解决步数
    int nodesGenerated;            // 生成的节点数
    int nodesExpanded;             // 扩展的节点数
    double timeElapsed;            // 搜索耗时（毫秒）
    
    SearchResult() : success(false), steps(0), nodesGenerated(0), nodesExpanded(0), timeElapsed(0.0) {}
};

// 搜索算法基类
class SearchAlgorithm
{
public:
    SearchAlgorithm();
    SearchAlgorithm(const std::string& name);
    virtual ~SearchAlgorithm();
    
    // 纯虚函数，子类必须实现
    virtual SearchResult search(const PuzzleState& initial, const PuzzleState& goal) = 0;
    
    // 获取算法名称
    virtual std::string getAlgorithmName() const { return algorithmName; }
    
    // 设置和获取最大搜索深度限制
    void setMaxDepth(int depth) { maxDepth = depth; }
    int getMaxDepth() const { return maxDepth; }
    
    // 设置和获取最大扩展节点数限制
    void setMaxNodes(int nodes) { maxNodes = nodes; }
    int getMaxNodes() const { return maxNodes; }
    
    // 设置和获取时间限制（秒）
    void setTimeLimit(double seconds) { timeLimit = seconds; }
    double getTimeLimit() const { return timeLimit; }
    
    // 检查是否应该停止搜索（基于限制条件）
    bool shouldStop(int nodesExpanded, int currentDepth, double elapsedTime) const;

protected:
    std::string algorithmName;      // 算法名称
    PuzzleState goalState;          // 目标状态
    int maxDepth;                   // 最大搜索深度限制
    int maxNodes;                   // 最大扩展节点数限制
    double timeLimit;               // 时间限制（秒）
    
    // 统计变量
    int nodesGenerated;             // 生成的节点数
    int nodesExpanded;              // 扩展的节点数
    
    // 重置计数器
    void resetCounters() { nodesGenerated = 0; nodesExpanded = 0; }
    
    // 从目标节点回溯构建解决方案
    std::vector<int> buildSolution(std::shared_ptr<SearchNode> goalNode) const;
    
    // 将动作转换为字符串描述
    std::string actionToString(int action) const;
};

#endif // SEARCHALGORITHM_H